/****************************************************************************
 * Copyright (C) 2025 Chenyz. All rights reserved.
 *
 * @file    TinyOS_Delay.c
 *
 * @par     dependencies
 *          - TinyOS_Delay.h
 *          - TinyOS_Task.h (for task management functions and variables)
 *
 * @author  Chenyz
 *
 * @brief   Task delay management module for TinyOS with following features:
 *          - Task delay initialization and management
 *          - Time-based task suspension and wake-up
 *          - Integration with task scheduler for automatic rescheduling
 *          - Critical section protection for thread-safe operations
 *          - Support for tick-based timing with system tick integration
 *          - Cross-platform compatibility (bare-metal/RTOS systems)
 *
 * @version V1.0
 * @date    2025-05-23
 *
 * @note    Coding standard:
 *          - 4 spaces per indent level
 *          - Follow MISRA-C 2012 guidelines
 *          - Compiler compatibility: C99 and above
 *
 ****************************************************************************/

#include "TinyOS_Delay.h"
#include "TinyOS_Task.h"

/**
 * @brief Initializes the task delay list
 * 
 * This function prepares the global task delay list for use by initializing
 * its internal structure. The delay list tracks all tasks that are currently
 * suspended waiting for a timeout.
 */
void TinyOS_TaskDelayedInit(void)
{
    TinyOS_ListInit(&TaskDelayList);
}

/**
 * @brief Places a task in the delayed state for a specified number of ticks
 * 
 * This function suspends a task for the given number of system ticks by
 * adding it to the delay list and updating its status to indicate it's delayed.
 * 
 * @param Task Pointer to the task control block to be delayed
 * @param Ticks Number of system ticks to delay the task
 */
void TinyOS_TaskDelayTimeWait(TinyOS_TaskType* Task, uint32_t Ticks)
{
    Task->TaskDelayTicks = Ticks;
    TinyOS_ListTailInsert(&TaskDelayList, &(Task->TaskDelayListNode));
    Task->TaskStatus |= TINYOS_TASK_DELAYED;
}

/**
 * @brief Wakes a task from the delayed state
 * 
 * This function removes a task from the delay list and clears its delayed status,
 * making it eligible for scheduling again.
 * 
 * @param Task Pointer to the task control block to be woken up
 */
void TinyOS_TaskDelayTimeWake(TinyOS_TaskType* Task)
{
    TinyOS_ListDeleteNode(&TaskDelayList, &(Task->TaskDelayListNode));
    Task->TaskStatus &= ~TINYOS_TASK_DELAYED;    
}

void TinyOS_TaskDelayListDelete(TinyOS_TaskType* Task)
{
    TinyOS_ListDeleteNode(&TaskDelayList, &(Task->TaskDelayListNode)); 
}

/**
 * @brief Delays the current task for a specified number of system ticks
 * 
 * This function suspends the current task for the given number of system ticks.
 * The task is removed from the ready list and placed in the delay list until
 * the specified time has elapsed. This function operates within a critical
 * section to ensure thread safety.
 * 
 * @param DelayTicks Number of system ticks to delay the task
 */
void TinyOS_TaskDelay(uint32_t DelayTicks)
{
    /* Enter critical section to protect task data structures */
    uint32_t Status = TinyOS_TaskEnterCritical();
    
    /* Place current task in delay state and remove from ready list */
    TinyOS_TaskDelayTimeWait(CurrentTask, DelayTicks);   
    TinyOS_TaskSchedulerUnReady(CurrentTask);
 
    /* Schedule another task while this one is delayed */
    TinyOS_TaskScheduler();
    
    /* Exit critical section */
    TinyOS_TaskExitCritical(Status);
}

